home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / basic / qbfaqr01.zip / DBASE.DOC < prev    next >
Text File  |  1992-03-08  |  9KB  |  238 lines

  1. ===========================================================================
  2.  BBS: PC Connect
  3. Date: 03-03-92 (20:46)             Number: 9964
  4. From: NICK DAVIS                   Refer#: NONE
  5.   To: FRANK HAGAN                   Recvd: NO  
  6. Subj: DATABASE                       Conf: (11) R-QBasic
  7. ---------------------------------------------------------------------------
  8. I created this TYPE-variable method of using the db/LIB routines for
  9. reading and writing dBASE-format files because normally this is a
  10. three-step process with db/LIB:
  11.  
  12. 1)  Get the record number, given a key, with GetKEY
  13. 2)  Get the record with GetREC
  14. 3)  Parse the record with multiple calls to GetFLD, one for each field
  15.  
  16. With over 600 data files and over 1,000 programs to worry about, I was
  17. overwhelmed by the number of lines of code I'd have to put in each
  18. program just to read and write records.  I was also concerned that if
  19. I didn't completely parse each record into its individual fields, I
  20. would invariably mix up data from different records, leading to
  21. disaster.  I was also afraid of trying to keep track of a gazillion
  22. variable names.  Therefore, I came up with this technique for using
  23. TYPE variables with db/LIB.
  24.  
  25. First, I created an INCLUDE file for each data file which describes
  26. its layout.  Note that the variable 'DeleteCode' must be the first
  27. because db/LIB adds it to keep track of whether or not a record has
  28. been deleted.  I used ten- or fewer-character variable subnames and
  29. made them match exactly the field names as db/LIB knew them.  Finally,
  30. the TYPE variable was made to match the file name for clarity's sake.
  31. Following is an abbreviated version of one of the INCLUDE files:
  32.  
  33.    TYPE CLIENTType'--------------------------------------------
  34. '
  35. '     |  File/Variable Name:  CLIENT
  36. '     |       Record Length:  184
  37. '     |         Description:  Client Master File
  38. '
  39.       DeleteCode    AS STRING * 1
  40. '     --------------------------D
  41.       KEY           AS STRING * 6'     CLIENT NO.
  42.       FIRM          AS STRING * 30'    Name of Firm
  43.       ADDRESS1      AS STRING * 30'    Address Line 1
  44.       ADDRESS2      AS STRING * 30'    Address Line 2
  45.       ADDRESS3      AS STRING * 30'    Address Line 3
  46.       CITY          AS STRING * 15'    City
  47.       STATE         AS STRING * 2'     State
  48.       ZIP           AS STRING * 10'    Zip Code
  49.       ATTENTION     AS STRING * 30'    Contact
  50.    END TYPE
  51. '
  52.    COMMON SHARED /Common.CLIENT/ CLIENT AS CLIENTType'   Variable
  53.    COMMON SHARED /Common.CLIENT/ DBF.CLIENT, NDX.CLIENT' File Handles
  54.  
  55. Next, I created another INCLUDE file for each data file to do some
  56. housework each time a data file was needed in a program.  One such is:
  57.  
  58.    OpenDBF DBF.CLIENT, Status, "CLIENT.DBF", DBFileType, mode
  59.    IF Status THEN PRINT "CLIENT"; Status: END
  60.    DBParams(DBF.CLIENT).Segment = VARSEG(CLIENT)
  61.    DBParams(DBF.CLIENT).Offset = VARPTR(CLIENT)
  62.    DBParams(DBF.CLIENT).Length = LEN(CLIENT)
  63.    OpenNDX NDX.CLIENT, Status, "CLIENT.NDX", NDXtype, NDXmode,_
  64.      KeyExp$, KeyLen, KeyType, mode
  65.    IF Status THEN PRINT "CLIENT"; Status: END
  66.  
  67. Note that the file handles which db/LIB creates for the data file and
  68. the index file are called DBF.FileName and NDX.FileName in each case -
  69. - again, keeping 600 files straight.
  70.  
  71. Finally, I created a general purpose INCLUDE file to go with every
  72. program.  It is:
  73.  
  74. '---------------------------------------------------------------------
  75. '              Parameters for dBASE File Read/Writes w/ TYPEs
  76. '---------------------------------------------------------------------
  77. '
  78.      TYPE dBParamsType
  79.           Segment   AS INTEGER
  80.           Offset    AS INTEGER
  81.           Length    AS INTEGER
  82.      END TYPE
  83. '
  84.      DIM dBParams(1 TO 100) AS dBParamsType
  85.      COMMON SHARED /Common.dBParams/ dBParams() AS dBParamsType
  86.  
  87. Note that the use of labelled COMMONs lets me freely add data file
  88. INCLUDE files to a program at any time without having to worry about
  89. conflict with existing COMMON blocks.
  90.  
  91. Then, a sample program would look something like this:
  92.  
  93.    DEFINT A-Z
  94. '$INCLUDE: 'CLIENT.BI'
  95. '$INCLUDE: 'DBPARAMS.BI'
  96.    mode = 0 ' Existing File (Add 16 for network use)
  97. '$INCLUDE: 'CLIENT.OP'
  98.  
  99. This last INCLUDE file is the one described above which opens a data
  100. file and its corresponding index file.
  101.  
  102. Then, to read or write any data file, I created the following three
  103. routines:
  104. '         SET a TYPE Variable to All Blanks
  105. SUB Blank.Rec (n) STATIC
  106. +++9╖E"▓╡k╓A▒─   FOR i =ATE0 S7=60 S11=75 V1 X4 s0=0
  107.  
  108. PCRelay:SPACE -> #606 RelayNet (tm)
  109. 4.11             Menlo Park, CA (415) 323-4193 * 10 lines 3gB
  110. ===========================================================================
  111.  BBS: PC Connect
  112. Date: 03-03-92 (23:09)             Number: 9975
  113. From: NICK DAVIS                   Refer#: 9964
  114.   To: FRANK HAGAN                   Recvd: NO  
  115. Subj: DATABASE (2/3)                 Conf: (11) R-QBasic
  116. ---------------------------------------------------------------------------
  117.  ----- Continued -----
  118.  
  119. Finally, I created a general purpose INCLUDE file, DBPARAMS.BI, to be
  120. used with every program.  It is:
  121.  
  122. '---------------------------------------------------------------------
  123. '              Parameters for dBASE File Read/Writes w/ TYPEs
  124. '---------------------------------------------------------------------
  125. '
  126.      TYPE dBParamsType
  127.           Segment   AS INTEGER
  128.           Offset    AS INTEGER
  129.           Length    AS INTEGER
  130.      END TYPE
  131. '
  132.      DIM dBParams(1 TO 100) AS dBParamsType
  133.      COMMON SHARED /Common.dBParams/ dBParams() AS dBParamsType
  134.  
  135. Note that the use of labelled COMMONs lets me freely add data file
  136. INCLUDE files to a program at any time without having to worry about
  137. conflict with existing COMMON blocks.
  138.  
  139. Then, a sample program would look something like this:
  140.  
  141.    DEFINT A-Z
  142. '$INCLUDE: 'CLIENT.BI'
  143. '$INCLUDE: 'DBPARAMS.BI'
  144.    mode = 0 ' Existing File (Add 16 for network use)
  145. '$INCLUDE: 'CLIENT.OP'
  146.  
  147. This last INCLUDE file is the one described above which opens a data
  148. file and its corresponding index file.
  149.  
  150. Then, to read or write any data file, I created the following three
  151. routines:
  152. '         SET a TYPE Variable to All Blanks
  153. SUB Blank.Rec (n) STATIC
  154.    Segment = DBParams(n).Segment
  155.    Firstx = DBParams(n).Offset
  156.    First& = Firstx - (Firstx < 0) * 65536
  157.    Last& = First& + DBParams(n).Length - 1
  158.    DEF SEG = Segment
  159.    FOR i& = First& TO Last&: POKE i&, 32: NEXT
  160.    DEF SEG
  161. END SUB
  162. '         GET a Record into a TYPE Variable
  163. SUB GetFullREC (FileNumber, Status, RecordNumber#) STATIC
  164.    GetREC FileNumber, Status, RecordNumber#, a$
  165.    IF Status THEN EXIT SUB'        db/LIB ERROR
  166.    IF LEFT$(a$, 1) = "*" THEN Status = -1: EXIT SUB'  Record Deleted
  167.    ASegment = SSEG(a$)
  168.    AOffsetx = SADD(a$)
  169.    AOffset& = AOffsetx - (AOffsetx < 0) * 65536
  170.    Segment = DBParams(FileNumber).Segment
  171.    Offsetx = DBParams(FileNumber).Offset
  172.    Offset& = Offsetx - (Offsetx < 0) * 65536
  173.    L = LEN(a$) - 1
  174.    FOR i = 0 TO L
  175.       DEF SEG = ASegment:      n = PEEK(AOffset& + i)
  176.       DEF SEG = Segment:       POKE Offset& + i, n
  177.    NEXT
  178.    DEF SEG
  179. END SUB
  180.  
  181.  ----- Continued Next Message -----
  182.  
  183. PCRelay:SPACE -> #606 RelayNet (tm)
  184. 4.11             Menlo Park, CA (415) 323-4193 * 10 lines 3gB
  185. ===========================================================================
  186.  BBS: PC Connect
  187. Date: 03-03-92 (23:10)             Number: 9976
  188. From: NICK DAVIS                   Refer#: 9964
  189.   To: FRANK HAGAN                   Recvd: NO  
  190. Subj: DATABASE (3/3)                 Conf: (11) R-QBasic
  191. ---------------------------------------------------------------------------
  192.  ----- Continued -----
  193.  
  194. '         PUT a TYPE Variable into a Record
  195. SUB PutFullREC (FileNumber, Status, RecordNumber#) STATIC
  196.    Length = DBParams(FileNumber).Length
  197.    a$ = STRING$(Length, 32)
  198.    ASegment = SSEG(a$)
  199.    AOffsetx = SADD(a$)
  200.    AOffset& = AOffsetx - (AOffsetx < 0) * 65536
  201.    Segment = DBParams(FileNumber).Segment
  202.    Offsetx = DBParams(FileNumber).Offset
  203.    Offset& = Offsetx - (Offsetx < 0) * 65536
  204.    L = Length - 1
  205.    FOR i = 0 TO L
  206.       DEF SEG = Segment:       n = PEEK(Offset& + i)
  207.       DEF SEG = ASegment:      POKE AOffset& + i, n
  208.    NEXT
  209.    DEF SEG
  210.    PutREC FileNumber, Status, RecordNumber#, a$
  211. END SUB
  212.  
  213. Then, assuming that I've used GetKEY to get a record number given a
  214. key, I can then use:
  215.  
  216.    Blank.Rec DBF.CLIENT'  -- Just in case
  217.    GetFullREC DBF.CLIENT, Status, record#
  218.  
  219. I now have available CLIENT.KEY, CLIENT.FIRM, etc., assuming that
  220. Status = 0.
  221.  
  222. All the PEEK and POKE stuff above can be avoided (and the program
  223. speeded up) if you have a block memory move routine such as BCopy from
  224. QuickPack Pro.
  225.  
  226. I know that this seems like a lot of overhead to worry about, but once
  227. these building blocks are in place, life becomes a lot easier
  228. witq┘db/LIB, particularly in some of my programs which open 40+ files at
  229. once.  Note that I've left out all the stuff related to checking to
  230. see if a record is locked in a network environment, but that's a story
  231. for another day.
  232.  
  233. == Nick ==
  234.  
  235.  
  236. PCRelay:SPACE -> #606 RelayNet (tm)
  237. 4.11             Menlo Park, CA (415) 323-4193 * 10 lines 3gB
  238.